package com.admin.business.sys;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.admin.business.background.entityClasses.VenusSysMenu;
import com.admin.business.background.venusOaAttendancePunishSet.VenusOaAttendancePunishSetDao;
import com.admin.business.background.venusOaClockEquipment.VenusOaClockEquipmentDao;
import com.admin.business.background.venusOaControlOverInvoices.VenusOaControlOverInvoicesDao;
import com.admin.business.background.venusOaDepositAdmin.VenusOaDepositAdminDao;
import com.admin.business.background.venusOaInsurance.VenusOaInsuranceDao;
import com.admin.business.background.venusOaLeaveApproval.VenusOaLeaveApprovalDao;
import com.admin.business.background.venusOaLitigation.VenusOaLitigationDao;
import com.admin.business.background.venusOaNotice.VenusOaNoticeDao;
import com.admin.business.background.venusOaOpinion.VenusOaOpinionDao;
import com.admin.business.background.venusOaOutsourcingCostCycle.VenusOaOutsourcingCostCycleDao;
import com.admin.business.background.venusOaPrizepunApprovalset.VenusOaPrizepunApprovalsetDao;
import com.admin.business.background.venusOaRaiseApproval.VenusOaRaiseApprovalDao;
import com.admin.business.background.venusOaStampApplication.VenusOaStampApplicationDao;
import com.admin.business.background.venusOrgAdapay.VenusOrgAdapayDao;
import com.admin.business.venusOrganizeEmployee.VenusOrganizeEmployeeDao;
import com.admin.business.venusSysMenu.VenusSysMenuDao;
import com.admin.business.venusSysRole.VenusSysRoleDao;
import com.admin.utils.RedisUtilKey;
import com.tiangong.framework.annotation.OpenApi;
import com.tiangong.framework.bo.CDO;
import com.tiangong.framework.bo.ObjectArray;
import com.tiangong.framework.bo.Return;
import com.zmbsms.os.core.util.ObjectUtils;
import com.zmbsms.os.core.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@DS("user")
@Service("userMenu")
@Slf4j
public class userMenuService {

	@Autowired
	private RedisUtilKey redisTemplate;
	@Resource
	VenusOrganizeEmployeeDao venusOrganizeEmployeeDao;

	@Resource
	VenusSysRoleDao venusSysRoleDao;
	@Resource
	VenusSysMenuDao venusSysMenuDao;
	@Resource
	VenusOrgAdapayDao venusOrgAdapayDao;

	@Resource
	VenusOaOpinionDao venusOaOpinionDao;

	@Resource
	VenusOaStampApplicationDao venusOaStampApplicationDao;

	@Resource
	VenusOaRaiseApprovalDao venusOaRaiseApprovalDao;

	@Resource
	VenusOaLeaveApprovalDao venusOaLeaveApprovalDao;
	@Resource
	VenusOaAttendancePunishSetDao venusOaAttendancePunishSetDao;
	@Resource
	VenusOaControlOverInvoicesDao venusOaControlOverInvoicesDao;

	@Resource
	VenusOaOutsourcingCostCycleDao venusOaOutsourcingCostCycleDao;

	@Resource
	VenusOaInsuranceDao venusOaInsuranceDao;

	@Resource
	VenusOaLitigationDao venusOaLitigationDao;

	@Resource
	VenusOaNoticeDao venusOaNoticeDao;

	@Resource
	VenusOaPrizepunApprovalsetDao venusOaPrizepunApprovalsetDao;

	@Resource
	VenusOaDepositAdminDao venusOaDepositAdminDao;



	/**
	 * 1.前端返回存储的的 token
	 * 2.查询左侧菜单栏，查询左侧红点数据信息
	 */
	@OpenApi
	public Return sys_menu_by_user_left(CDO cdoRequest) {

		//根据返回标识存储获取公司的id 和当前人信息
		String token = cdoRequest.getString("token");
		String orgId=redisTemplate.get("org_"+token).toString();//获取redis存储公司
		Object o = redisTemplate.get(token);
		CDO cdo = CDO.copyToNewCDO(o);
		String userId = cdo.getString("userId");//人员id
		//权限new修改 权限修改
		Object liebiao = redisTemplate.get(orgId + "new" + userId);


		List<CDO> empList =venusOrganizeEmployeeDao.getMyPostByUsreId(orgId, userId);;


		HashSet<Long> orgSet = new HashSet<>();//去重
		HashSet<Long> proSet = new HashSet<>();//去重
		for (CDO cdo1 : empList) {
			if (StringUtils.isNotEmpty(cdo1.getString("employee_org_id"))) {
				orgSet.add(cdo1.getLong("employee_org_id"));
			}
			if (StringUtils.isNotEmpty(cdo1.getString("employee_project_id"))){
				proSet.add(cdo1.getLong("employee_project_id"));
			}
		}
		orgSet.add(-1L);
		proSet.add(-1L);

		if (liebiao!=null && ObjectUtils.isNotNull(liebiao) && !liebiao.toString().equals("[null]")){
			JSONArray jsonArray = JSONArray.fromObject(liebiao);
			List<CDO> menuList=  (List<CDO>)jsonArray.toCollection(jsonArray, CDO.class);
			for (CDO menu : menuList) {
				ObjectArray childFunctionList = menu.getObjectArray("childFunctionList");
				JSONArray jsonArray1 = JSONArray.fromObject(childFunctionList);
				List<CDO> menuListC1 = (List<CDO>) jsonArray1.toCollection(jsonArray1, CDO.class);

				String menuName = menu.getString("menuName");
				switch (menuName) {
					case "扫码收费管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
					case "企业管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "用章管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "工资管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "考勤管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "巡逻管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "通知公告":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "报销管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "押金管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "发票管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
//						物品管理
					case "外包管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "标准答案":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "保险理赔":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "诉讼管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "员工奖惩":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
					case "平台管理":
						menu = getReassignTheDataMenu(menu, menuListC1, token, orgSet, proSet);
						break;
				}
			}

			CDO menuCdo=new CDO();
			menuCdo.set("menuList",menuList);//以CDO做跳板，将menuList转化为ObjectArray
			ObjectArray menuList1 = menuCdo.getObjectArray( "menuList");
			JSONArray jsons = JSONArray.fromObject(menuList1);
			System.out.println(jsons);


			return Return.valueOf(jsons);
		}



		String m_type = cdoRequest.getString("m_type");
		if (StringUtils.isEmpty(m_type)){
			return Return.valueOf(400, "数据无效!", "");
		}
		Integer level = cdoRequest.getString("level")==null?0:Integer.valueOf(cdoRequest.getString("level"));

		List<VenusSysMenu> userVenusSysMenuList = get_menu_by_user_id(userId,Integer.valueOf(m_type),orgId,level);
		if (ObjectUtils.isNotNull(userVenusSysMenuList)){
			//2022-6-28 存贮权限键值由
			String key = orgId+ "new"+userId ;  // 当前操作人选择的总公司id + new + 用户user_id
			redisTemplate.set(key, JSONArray.fromObject(userVenusSysMenuList).toString());
		}

		return Return.valueOf(userVenusSysMenuList);
	}


	/**
	 * 把数据重新赋值
	 */
	public CDO getReassignTheDataMenu(CDO cdo,List<CDO> menuListC1,String token, HashSet<Long> orgSet, HashSet<Long> proSet){
		Integer dot =0;//红点总数据惨淡兰使用
		List<CDO> childFunctionList=new ArrayList<>();//重新创建接收菜单里头二级
		for (CDO menu2 : menuListC1) {
			CDO cdo1 = getMenuInformation(menu2, token,orgSet ,proSet);
			if (StringUtils.isNotEmpty(cdo1.getString("dot"))) {
				dot= dot+cdo1.getInteger("dot");
				menu2.set("dot", cdo1.getString("dot"));
			}
			childFunctionList.add(cdo1);//存储刚添加完红点信息
		}
		cdo.set("childFunctionList", childFunctionList);

		return cdo;
	}


	/**
	 * 获取菜单二级信息
	 */
	public CDO getMenuInformation(CDO cdo ,String token, HashSet<Long> orgSet, HashSet<Long> proSet){
		Integer redDots = getMenuRedDotsInformation(cdo,token,orgSet,proSet);
		if (redDots!=0){
			//菜单栏红点增加数量
			cdo.set("dot",redDots);
		}

		return cdo;
	}


	/**
	 * 菜单查询 红点信息
	 */
	public Integer getMenuRedDotsInformation(CDO cdo ,String token, HashSet<Long> orgSet, HashSet<Long> proSet){
		String orgId=redisTemplate.get("org_"+token).toString();//获取redis存储公司
		Object o = redisTemplate.get(token);
		CDO userInfo = CDO.copyToNewCDO(o);
		String userId = userInfo.getString("userId");//人员id
		
		
		Integer count=0;
		CDO user=new CDO();
		user.set("org_id",orgId);
		switch (cdo.getString("menuName")){
			case "申请开通支付":
				user.set("user_id",userId);
				int venusOrgAdapayCount = venusOrgAdapayDao.getVenusOrgAdapayCount(user);
				if(venusOrgAdapayCount==0){
					return venusOrgAdapayCount;
				}
				break;
			case "意见反馈":
				user.set("user_id",userId);
				List<CDO> countList = venusOaOpinionDao.getVenusOaOpinionNoResponse(user);
				if(countList.size()>0){
					return  countList.size();
				}
				break;
			case "待盖章":
				List<CDO> venusOaStampApplicationListPage = venusOaStampApplicationDao.getVenusOaStampApplicationListPage(user);
				int stampCont =0;
				for (CDO cdo1 : venusOaStampApplicationListPage) {
					user.set("stamp_type",cdo1.getString("stamp_type"));
					user.set("user_id",userId);
					user.set("pro_id",cdo1.getString("pro_id"));
					CDO stampInfo = venusOaStampApplicationDao.getVenusOaStampInstallDotInfo(user);
					if (stampInfo!=null){
						stampCont++;
					}
				}
				if (stampCont>0) {
					return stampCont;
				}
				break;
			case "用章待审批":
				user.set("user_id",userId);
				List<CDO> stampList = venusOaStampApplicationDao.getVenusOaStampApprovalDotList(user);
				if(stampList.size()>0){
					return  stampList.size();
				}
				break;
			case "加薪审批":
				user.set("approver_id",userId);
				user.set("approver_state",0);
				List<CDO> raiseApprovalList = venusOaRaiseApprovalDao.getVenusOaRaiseApprovalListPage(user);
				if(raiseApprovalList.size()>0){
					return  raiseApprovalList.size();
				}
				break;
			case "请假补卡申请":
				user.set("user_id",userId);
				List<CDO> leaveReplacementList = venusOaLeaveApprovalDao.getLeaveReplacementCardDotList(user);
				if(leaveReplacementList.size()>0){
					return  leaveReplacementList.size();
				}
				break;
			case "考勤处罚设置":
				List<CDO> attendancePunishSetList = venusOaAttendancePunishSetDao.getVenusOaAttendancePunishSetListPage(user);
				if(attendancePunishSetList.size()<0){
					return  attendancePunishSetList.size();
				}
				break;
			case "待退款":
				user.set("deposit_state",2);
				user.set("org_id",orgId);
				user.set("user_pro",userId);
				List<CDO> depositAdminList = venusOaDepositAdminDao.getVenusOaDepositAdminListPageByCondition(user);
				if(depositAdminList.size()>0){
					return  depositAdminList.size();
				}
				break;
			case "待开票":
				user.set("company_id",orgId);
				user.set("invoice_status",2);
				List<CDO> controlOverInvoicesList = venusOaControlOverInvoicesDao.getVenusOaControlOverInvoicesListPage(user);
				if(controlOverInvoicesList.size()>0){
					return  controlOverInvoicesList.size();
				}
			case "已开票":
				user.set("company_id",orgId);
				user.set("has_make_out_an_invoice",1);
				List<CDO> controlOverInvoicesLis = venusOaControlOverInvoicesDao.getVenusOaControlOverInvoicesListPage(user);
				if(controlOverInvoicesLis.size()>0){
					return  controlOverInvoicesLis.size();
				}
				break;
			case "开票设置":
				CDO controlOverOrgId = venusOaControlOverInvoicesDao.getVenusOaControlOverInvoicesInstallByOrgId(user);
				if (controlOverOrgId==null){
					return count++;
				}
				break;
			case "支出外包单位":
				user.set("classS",2);
				user.set("org",orgId);
				user.set("payment_status",2);
				user.set("iscancel", 0);
				user.set("cooperation_status", 1);
				List<CDO> outlayOutsourcing = venusOaOutsourcingCostCycleDao.getInComeList(user);
				Integer outlaycount=0;
				for (CDO cdo1 : outlayOutsourcing) {
					Date pay_begin_time = cdo1.getDate("pay_begin_time");//获取缴费开始时间
					Long charging_time = cdo1.getLong("charging_time");//获取收费提示时间 每期收费，到期前几天提示
					long diff =pay_begin_time.getTime()-new Date().getTime() ;//这样得到的差值是毫秒级别
					long days = diff / (1000 * 60 * 60 * 24);
					if (days<charging_time&&days>0||pay_begin_time.before(new Date())){//前x天提示 并且没有超过开始时间
						outlaycount++;
					}
				}
				if(outlaycount>0){
					return  outlaycount;
				}
				break;
			case "收入外包单位":
				user.set("classS",1);
				user.set("org",orgId);
				user.set("payment_status",2);
				user.set("iscancel", 0);
				user.set("cooperation_status", 1);
				List<CDO> revenueOutsourcing = venusOaOutsourcingCostCycleDao.getInComeList(user);
				for (CDO cdo1 : revenueOutsourcing) {
					Date pay_begin_time = cdo1.getDate("pay_begin_time");//获取缴费开始时间
					Long charging_time = cdo1.getLong("charging_time");//获取收费提示时间 每期收费，到期前几天提示
					long diff =pay_begin_time.getTime()-new Date().getTime() ;//这样得到的差值是毫秒级别
					long days = diff / (1000 * 60 * 60 * 24);
					if (days<charging_time&&days>0||pay_begin_time.before(new Date())){//前x天提示 并且没有超过开始时间
						count++;
					}
				}
				if(count>0){
					return  count;
				}
				break;
			case "理赔待处理":
				user.set("daoHang", 0);//代表0,5
				List<CDO> insuranceListReddots = venusOaInsuranceDao.getVenusOaInsuranceListReddots(user);
				for (CDO ins : insuranceListReddots) {
					CDO empDate = new CDO();
					empDate.set("sys_user_id", userId);//当前登录人信息
					empDate.set("initial_audit", ins.getString("initial_audit"));//1.公司2.项目3.岗位',
					empDate.set("initial_position", ins.get("initial_position"));//项目 和公司 和岗位
					List<CDO> venusOaEmployees = venusOaInsuranceDao.getVenusOaEmployees(empDate);
					if (venusOaEmployees.size() > 0) {//查到人员就添加
						return count++;
					}
				}
				break;
			case "理赔审核列表":
				user.set("superiors", userId);//代表0,5
				user.set("ins_state", 2);//代表0,5
				List<CDO> insuranceShehe = venusOaInsuranceDao.getVenusOaInsuranceShehe(user);
				if (insuranceShehe.size() > 0) {//查到人员就添加
					return insuranceShehe.size();
				}
				break;
			case "理赔设置":
				user.set("orgSet",orgSet);
				List<CDO> insuranceClaimsByOrgId = venusOaInsuranceDao.getVenusOaInsuranceClaimsByOrgId(user);
				Integer insCountClaims=0;
				if (orgSet.size()-1!=insuranceClaimsByOrgId.size()){
					return   insCountClaims++;
				}
				break;
			case "待赔付列表":
				user.set("superiors",userId);
				user.set("ins_state",3);
				List<CDO> insuranceShehe1 = venusOaInsuranceDao.getVenusOaInsuranceShehe(user);
				if (insuranceShehe1.size()>0){
					return insuranceShehe1.size();
				}
				break;
			case "奖惩设置":
				user.set("state",0);
				List<CDO> prizepunApprovalsetList = venusOaPrizepunApprovalsetDao.getVenusOaPrizepunApprovalsetListPage(user);
				if (prizepunApprovalsetList.size()>0){
					return prizepunApprovalsetList.size();
				}
				break;
		}

		return count;
	}




	/**
	 *
	 *   2020-08-19
	 *  暂停开发新功能、找bug、然后整理代码。
	 *
	 *  权限相关任务计划
	 *
	 * 	 需要修复 bug
	 *  【*】删除 人员 时需要相关的岗位权限信息 、依据此岗位权限删除对应的关联信息、避免删除多个岗位相关权限[√]
	 *  【*】创建组织架构同时授权菜单需要排除功能按钮的显示和隐藏 [√]
	 *  【*】岗位 可能 出现 多个 上级部门、多个部门就意味着有多个角色信息 。
	 *  	多个部门就意味着有多个上级项目、公司、同时又有多个角色信息、
	 *  	多个项目有同属于多个公司的可能、又出现多个角色信息[√]
	 *  【#】增加部门、公司的数据权限筛选接口 [√]
	 *  【*】级联的公司、项目、部门、岗位的数据权限过滤 [√]
	 *
	 *  …………………………………………………………………修改…………………………………………………………………………………
	 *  【*】多个岗位权限 对应 一个员工 找到多个岗位权限、然后合并  []
	 *
	 *  新增加 的功能
	 *  【#】一个多岗 一个人可以同时拥有多个岗位、
	 *  	解除添加人员单一岗位限制、这是比较复杂【一个母公司下可以多个岗位、其他母公司不允许添加?】
	 *      【条件：只要出现全职就不允许入职、如果想要入职必须改为兼职、同一母公司下。】
	 *
	 *
	 *  【#】调岗、原始岗位对应的权限信息清除员工关联、
	 *  	新岗位对应的权限增加员工关联、改变员工对应的岗位信息 []
	 *
	 *  【#】增加员工状态【在职、离职、停职、开除】
	 *
	 *
	 *  —————————————————————————修改过的———————————————————————————
	 *  【@-1】删除 人员 时需要相关的岗位权限信息 、
	 *        依据此岗位权限删除对应的关联信息、
	 *        避免删除多个岗位相关权限
	 *  [√] 已进行线下测试。
	 *
	 *  【@-2】创建组织架构同时授权菜单需要排除功能按钮的显示和隐藏
	 *  [√] 已进行线下测试。
	 *
	 *  【@-3】多个岗位可能属于多个部门、
	 *  	     多个部门可能属于多个项目或者多个公司
	 *  	     多个项目可能属于多个公司
	 *  [√] 没有进行线下测试。
	 *
	 *  【@-4】级联的公司、项目、部门、岗位的数据权限过滤处理
	 *  [√] 没有进行线下测试。
	 *
	 *  【@-5】调岗、原始岗位对应的权限信息清除与员工关联
	 *  	     新岗位对应的权限增加和员工关联
	 *  	     改变员工对应的岗位信息
	 *  [√] 没有进行线下测试。
	 * *********************************************************************
	 *  						查看  权限	接口处理
	 * *********************************************************************
	 */
	/**
	 * 根据系统用户  查看 对应的 菜单权限
	 * @param user_id 系统用户ID
	 * @param menu_type 系统菜单类型  如果为 0 则展示全部 如果为1 则加载 菜单权限 如果为2 则加载功能权限
	 * @return
	 *
	 */
	public List<VenusSysMenu> get_menu_by_user_id(String user_id, Integer menu_type, String org_id, Integer level) {
		//例子：//2141,1,53,0
		//找到对应的所有角色、找到角色对应的所有菜单、去重、递归找到所有父节点、去重、然后找到菜单的所有信息
		/// 用户 关联多个角色
		level=0;

		//如果有设置过个人权限，则走个人功能权限,menu_ids中包含了个人权限
		List<String> menu_ids=venusSysRoleDao.get_role_menu_by_user_id(user_id,0,org_id,level);//2022-4-23加载岗位及个人权限所有

		// 查询有没有个人权限
		if(menu_ids!=null&&menu_ids.size()>0) {
			// 获取 对应的 菜单

			List<String> collect = menu_ids.parallelStream().distinct().collect(Collectors.toList());
			CDO menus=new CDO();
			menus.set("list", collect);

			List<VenusSysMenu> get_menu_by_menus = venusSysMenuDao.get_menu_by_menus(menus);
			System.out.println(get_menu_by_menus);
			if (ObjectUtils.isNotNull(get_menu_by_menus)){
				Map<Integer,VenusSysMenu> map=new HashMap<>();
				for (VenusSysMenu menu:get_menu_by_menus){
					map.put(menu.getMenuId(),menu);
					//2023-03-10 新增默认权限默认被选中 无法选择 zwl
					CDO cdo = venusSysMenuDao.getTacitAuthority(menu.getMenuId());
					if (cdo!=null) menu.setForbidden(true);//有数据代表为默认权限
				}
				menus.set("list", get_menu_by_menus);
				List<VenusSysMenu> parentList=venusSysMenuDao.getParentList(menus);

				if (ObjectUtils.isNotNull(parentList)){
					for (VenusSysMenu menuP:parentList){
						if (ObjectUtils.isNull(map.get(menuP.getMenuId()))){
							get_menu_by_menus.add(menuP);
						}
					}
				}
				if (menu_type==1) {//去掉功能权限
					for (int i=get_menu_by_menus.size()-1;i>=0;i--){
						if(get_menu_by_menus.get(i).getMenuType()==2){
							get_menu_by_menus.remove(i);
						}
					}
				}
				List<VenusSysMenu> getAllListTree = getAllList(0L,get_menu_by_menus);
				return getAllListTree;
			}
		}
		return null;
	}
















	/**
	 * 递归菜单处理父子关系
	 */
	public List<VenusSysMenu> getAllList(Long parentId, List<VenusSysMenu> list){
		List<VenusSysMenu> childList=new ArrayList<>();
		if (ObjectUtils.isNotNull(list)){
			for (VenusSysMenu sys:list){
				if (sys.getMenuType()!=1){
					sys.setMenuSign(sys.getMenuUrl());
					sys.setMenuUrl("");
				}
				if (parentId.longValue()==sys.getMenuParentId()){
					sys.setChildFunctionList(getAllList(Long.parseLong(sys.getMenuId()+""),list));
					childList.add(sys);
				}
			}
		}
		//2023-03-20 新增排序 zwl
		childList.sort(Comparator.comparing(VenusSysMenu::getMenuSort));
		return childList;
	}




}
